/**
 * Copyright (C) 2021-2022 maminjie <canpool@163.com>
 * SPDX-License-Identifier: LGPL-2.1
 * Powered by Qt-Advanced-Docking-System
**/

#include "dockfloatingwidgettitlebar.h"

#include "dockmanager_p.h"
#include "docktab_p.h"
#include "dockfloatingwidget.h"

#include <QHBoxLayout>
#include <QMouseEvent>
#include <QPixmap>
#include <QStyle>
#include <QToolButton>

QADS_BEGIN_NAMESPACE

class DockFloatingWidgetTitleBarPrivate
{
public:
    DockFloatingWidgetTitleBarPrivate(DockFloatingWidgetTitleBar *parent);

    void init();

public:
    DockFloatingWidgetTitleBar *q;
    QLabel *m_iconLabel = nullptr;
    DockTabLabel *m_titleLabel = nullptr;
    QToolButton *m_closeButton = nullptr;
    QToolButton *m_maximizeButton = nullptr;
    DockFloatingWidget *m_floatingWidget = nullptr;
    DragState m_dragState = DraggingInactive;
    QIcon m_maximizeIcon;
    QIcon m_normalIcon;
    bool m_maximized = false;
};

DockFloatingWidgetTitleBarPrivate::DockFloatingWidgetTitleBarPrivate(DockFloatingWidgetTitleBar *parent)
    : q(parent)
{}

void DockFloatingWidgetTitleBarPrivate::init()
{
    m_titleLabel = new DockTabLabel();
    m_titleLabel->setElideMode(Qt::ElideRight);
    m_titleLabel->setText(m_floatingWidget->windowTitle());
    m_titleLabel->setObjectName("floatingTitleLabel");
    m_titleLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    m_maximizeButton = new QToolButton();
    m_maximizeButton->setObjectName("floatingTitleMaximizeButton");
    m_maximizeButton->setAutoRaise(true);
    q->setMaximizedIcon(false);
    m_maximizeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    m_maximizeButton->setVisible(true);
    m_maximizeButton->setFocusPolicy(Qt::NoFocus);
    QObject::connect(m_maximizeButton, &QToolButton::clicked, q, &DockFloatingWidgetTitleBar::maximizeRequested);

    m_closeButton = new QToolButton();
    m_closeButton->setObjectName("floatingTitleCloseButton");
    m_closeButton->setAutoRaise(true);
    internal::setButtonIcon(m_closeButton, QStyle::SP_TitleBarCloseButton, QAds::FloatingWidgetCloseIcon);
    m_closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    m_closeButton->setIconSize(QSize(14, 14));
    m_closeButton->setVisible(true);
    m_closeButton->setFocusPolicy(Qt::NoFocus);
    QObject::connect(m_closeButton, &QToolButton::clicked, q, &DockFloatingWidgetTitleBar::closeRequested);

    QFontMetrics fontMetrics(m_titleLabel->font());
    int spacing = qRound(fontMetrics.height() / 4.0);

    // Fill the layout
    QBoxLayout *layout = new QBoxLayout(QBoxLayout::LeftToRight);
    layout->setContentsMargins(6, 0, 0, 0);
    layout->setSpacing(0);
    q->setLayout(layout);
    layout->addWidget(m_titleLabel, 1);
    layout->addSpacing(spacing);
    layout->addWidget(m_maximizeButton);
    layout->addWidget(m_closeButton);
    layout->setAlignment(Qt::AlignCenter);

    m_titleLabel->setVisible(true);
}

DockFloatingWidgetTitleBar::DockFloatingWidgetTitleBar(DockFloatingWidget *parent)
    : QWidget(parent)
    , d(new DockFloatingWidgetTitleBarPrivate(this))
{
    d->m_floatingWidget = parent;
    d->init();

    auto normalPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, 0, d->m_maximizeButton);
    d->m_normalIcon.addPixmap(normalPixmap, QIcon::Normal);
    d->m_normalIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);

    auto maxPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarMaxButton, 0, d->m_maximizeButton);
    d->m_maximizeIcon.addPixmap(maxPixmap, QIcon::Normal);
    d->m_maximizeIcon.addPixmap(internal::createTransparentPixmap(maxPixmap, 0.25), QIcon::Disabled);
    setMaximizedIcon(d->m_maximized);
}

DockFloatingWidgetTitleBar::~DockFloatingWidgetTitleBar()
{
    delete d;
}

void DockFloatingWidgetTitleBar::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        d->m_dragState = DraggingFloatingWidget;
        d->m_floatingWidget->startDragging(event->pos(), d->m_floatingWidget->size(), this);
        return;
    }

    QWidget::mousePressEvent(event);
}

void DockFloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *event)
{
    d->m_dragState = DraggingInactive;

    if (d->m_floatingWidget) {
        d->m_floatingWidget->finishDragging();
    }

    QWidget::mouseReleaseEvent(event);
}

void DockFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *event)
{
    if (!(event->buttons() & Qt::LeftButton) || d->m_dragState == DraggingInactive) {
        d->m_dragState = DraggingInactive;
        QWidget::mouseMoveEvent(event);
        return;
    }

    // move floating window
    if (d->m_dragState == DraggingFloatingWidget) {
        if (d->m_floatingWidget->isMaximized()) {
            d->m_floatingWidget->showNormal();
        }
        d->m_floatingWidget->moveFloating();
        QWidget::mouseMoveEvent(event);
        return;
    }

    QWidget::mouseMoveEvent(event);
}

void DockFloatingWidgetTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        emit maximizeRequested();
        event->accept();
    } else {
        QWidget::mouseDoubleClickEvent(event);
    }
}

QIcon DockFloatingWidgetTitleBar::maximizeIcon() const
{
    return d->m_maximizeIcon;
}

void DockFloatingWidgetTitleBar::setMaximizeIcon(const QIcon &icon)
{
    d->m_maximizeIcon = icon;
    if (d->m_maximized) {
        setMaximizedIcon(d->m_maximized);
    }
}

QIcon DockFloatingWidgetTitleBar::normalIcon() const
{
    return d->m_normalIcon;
}

void DockFloatingWidgetTitleBar::setNormalIcon(const QIcon &icon)
{
    d->m_normalIcon = icon;
    if (!d->m_maximized)  {
        setMaximizedIcon(d->m_maximized);
    }
}

void DockFloatingWidgetTitleBar::setClosable(bool enable)
{
    d->m_closeButton->setEnabled(enable);
}

void DockFloatingWidgetTitleBar::setTitle(const QString &text)
{
    d->m_titleLabel->setText(text);
}

void DockFloatingWidgetTitleBar::updateStyle()
{
    internal::repolishStyle(this, internal::RepolishDirectChildren);
}

/**
 * Change the maximize button icon according to current windows state
 */
void DockFloatingWidgetTitleBar::setMaximizedIcon(bool maximized)
{
    d->m_maximized = maximized;
    if (maximized) {
        d->m_maximizeButton->setIcon(d->m_normalIcon);
    } else {
        d->m_maximizeButton->setIcon(d->m_maximizeIcon);
    }
}

void DockFloatingWidgetTitleBar::enableCloseButton(bool enable)
{
    d->m_closeButton->setEnabled(enable);
}

QADS_END_NAMESPACE
